using System.Windows.Forms;

namespace 多线程窗体
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("单线程做菜，占用了UI线程。");
            Thread.Sleep(3000);
            MessageBox.Show("开始做菜了");
            Thread.Sleep(5000);
            MessageBox.Show("菜做好了");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(() =>
            {
                MessageBox.Show("多线程做菜，不占用了UI线程。");
                Thread.Sleep(3000);
                MessageBox.Show("开始做菜了");
                Thread.Sleep(5000);
                MessageBox.Show("菜做好了");
            });
            thread.Start();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //Task task = new Task(() => {
            //    MessageBox.Show("多线程做菜，不占用了UI线程。");
            //    Thread.Sleep(3000);
            //    MessageBox.Show("开始做菜了");
            //    Thread.Sleep(5000);
            //    MessageBox.Show("菜做好了");
            //});
            //task.Start();

            Task.Run(() =>
            {
                MessageBox.Show("多线程做菜，不占用了UI线程。");
                Thread.Sleep(3000);
                MessageBox.Show("开始做菜了");
                Thread.Sleep(5000);
                MessageBox.Show("菜做好了");
            });
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                Thread.Sleep(3000);
                MessageBox.Show("开始做素菜了...");
                Thread.Sleep(5000);
                MessageBox.Show("素菜做好了!");
            });

            Task.Run(() =>
            {
                Thread.Sleep(3000);
                MessageBox.Show("开始做荤菜了...");
                Thread.Sleep(5000);
                MessageBox.Show("荤菜做好了!");
            });
        }

        // 异步方法，不占用UI线程
        private async void button5_Click(object sender, EventArgs e)
        {
            // await 等待执行完
            await Task.Run(() =>
            {
                Thread.Sleep(3000);
                MessageBox.Show("开始做素菜了...");
                Thread.Sleep(5000);
                MessageBox.Show("素菜做好了!");
            });

            // await 等待执行完
            await Task.Run(() =>
            {
                Thread.Sleep(3000);
                MessageBox.Show("开始做荤菜了...");
                Thread.Sleep(5000);
                MessageBox.Show("荤菜做好了!");
            });




            // 这个要最后执行
            MessageBox.Show("素菜，荤菜都做好了，可以吃饭了!");
        }

        private void button6_Click(object sender, EventArgs e)
        {
            List<Task> list = new List<Task>();
            list.Add(Task.Run(() =>
            {
                Thread.Sleep(3000);
                MessageBox.Show("开始做素菜了...");
                Thread.Sleep(5000);
                MessageBox.Show("素菜做好了!");

            }));
            list.Add(Task.Run(() =>
            {
                Thread.Sleep(3000);
                MessageBox.Show("开始做荤菜了...");
                Thread.Sleep(5000);
                MessageBox.Show("荤菜做好了!");

            }));

            Task.WhenAll(list).ContinueWith((a) =>
            {
                MessageBox.Show("素菜，荤菜都做好了，可以吃饭了!");
            });

        }

        private void button7_Click(object sender, EventArgs e)
        {
            TaskFactory factory = new TaskFactory();
            factory.StartNew(() =>
            {
                MessageBox.Show("多线程做菜，不占用了UI线程。");
                Thread.Sleep(3000);
                MessageBox.Show("开始做菜了");
                Thread.Sleep(5000);
                MessageBox.Show("菜做好了");
            });
        }

        private void button8_Click(object sender, EventArgs e)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            cts.CancelAfter(5000);
            while (true)
            {
                Console.WriteLine("任务执行中！");
                if (cts.IsCancellationRequested)
                {
                    Console.WriteLine("任务被取消！");
                    break;
                }
            }
        }

        private void DoWork(object state)
        {
            CancellationToken token = (CancellationToken)state;
            // 检查取消令牌，并在必要时停止任务
            while (!token.IsCancellationRequested)
            {
                MessageBox.Show("任务进行中");
            }
            MessageBox.Show("任务结束");
        }

        private void button9_Click(object sender, EventArgs e)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            CancellationToken token = cts.Token;
            Task task = new Task(DoWork, token);
            task.Start();

            // 5秒后取消任务
            Thread.Sleep(5000);
            cts.Cancel();
        }

        private void button10_Click(object sender, EventArgs e)
        {
            // 创建一个CancellationTokenSource实例，它将用于请求取消操作。  
            CancellationTokenSource cts = new CancellationTokenSource();
            CancellationToken token = cts.Token;



            try
            {
                // 启动一个Task，并将CancellationToken作为参数传递给它。  
                Task task = Task.Run(() =>
                {
                    // 检查是否请求了取消操作。  
                    while (!token.IsCancellationRequested)
                    {
                        MessageBox.Show("工作中...");
                        // 执行其他代码...  
                        Thread.Sleep(5000);
                    }
                    MessageBox.Show("停止");
                    // 如果请求了取消操作，则抛出OperationCanceledException异常。  
                    throw new OperationCanceledException(token);
                }, token);
            }
            catch (Exception ex)
            {
                MessageBox.Show("捕获了异常");
            }


            Thread.Sleep(2000);
            // 在某个时候请求取消操作。这会触发所有挂起的取消请求。如果Task正在执行取消请求的操作，它将抛出OperationCanceledException异常。  
            cts.Cancel(); // 或者cts.Cancel(throwIfCancellationRequested: true);如果你想在取消时抛出异常。
        }

        private void button11_Click(object sender, EventArgs e)
        {
            // 创建一个CancellationTokenSource实例，它将用于请求取消操作。  
            CancellationTokenSource cts = new CancellationTokenSource();
            CancellationToken token = cts.Token;

            // 启动一个Task，并将CancellationToken作为参数传递给它。  
            Task task = Task.Run(() =>
            {
                try
                {
                    // 检查是否请求了取消操作。  
                    while (!token.IsCancellationRequested)
                    {
                        MessageBox.Show("工作中...");
                        // 执行其他代码...  
                        Thread.Sleep(5000);
                    }
                    MessageBox.Show("停止");
                    // 如果请求了取消操作，则抛出OperationCanceledException异常。  
                    throw new OperationCanceledException(token);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("捕获了异常");
                }
            }, token);

            Thread.Sleep(2000);
            // 在某个时候请求取消操作。这会触发所有挂起的取消请求。如果Task正在执行取消请求的操作，它将抛出OperationCanceledException异常。  
            cts.Cancel(); // 或者cts.Cancel(throwIfCancellationRequested: true);如果你想在取消时抛出异常。
        }

        private void button12_Click(object sender, EventArgs e)
        {
            MessageBox.Show($"主线程:{Thread.CurrentThread.ManagedThreadId}");
            Task task = new Task(() =>
            {
                MessageBox.Show($"子线程:{Thread.CurrentThread.ManagedThreadId}");
            });
            task.Start();
            MessageBox.Show($"主线程:{Thread.CurrentThread.ManagedThreadId}");
        }

        private void button13_Click(object sender, EventArgs e)
        {
            MessageBox.Show($"主线程:{Thread.CurrentThread.ManagedThreadId}");
            Task.Run(() =>
            {
                MessageBox.Show($"子线程:{Thread.CurrentThread.ManagedThreadId}");
            });
            MessageBox.Show($"主线程:{Thread.CurrentThread.ManagedThreadId}");
        }

        private void button14_Click(object sender, EventArgs e)
        {
            MessageBox.Show($"主线程:{Thread.CurrentThread.ManagedThreadId}");
            Task task = Task.Factory.StartNew(() =>
            {
                MessageBox.Show($"子线程:{Thread.CurrentThread.ManagedThreadId}");
            });
            //task.Start();
            MessageBox.Show($"主线程:{Thread.CurrentThread.ManagedThreadId}");
        }

        private void button15_Click(object sender, EventArgs e)
        {
            MessageBox.Show($"主线程:{Thread.CurrentThread.ManagedThreadId}");
            TaskFactory factory = new TaskFactory();
            factory.StartNew(() =>
            {
                MessageBox.Show($"子线程:{Thread.CurrentThread.ManagedThreadId}");
            });
            MessageBox.Show($"主线程:{Thread.CurrentThread.ManagedThreadId}");
        }

        private void button16_Click(object sender, EventArgs e)
        {
            Thread.Sleep(3000); // 这个是阻塞了主线程
            MessageBox.Show("主线程等待了3秒");
            Task.Delay(3000).ContinueWith((t, x) =>
            {
                MessageBox.Show("延迟执行了3秒");
            },null); // 这个不会阻塞主线程
            MessageBox.Show("主线程继续执行");
        }
    }
}
